/*
** Surprise Attack (Konami, 1990)
**
** This is a test for both:
** - the Konami CPU emulator
** - the scheduler (let's see those YM2151 timers work!)
**
** driver technical notes
** 0xe1bf starts a song (argument passed in accumulator)
*/


#include "smse2kincludes.h"
#include "SoundDeviceFactory.h"
#include "CPUFactory.h"
#include "Konami.h"
#include "SADriver.h"


/*
static ADDRESS_MAP_START( surpratk_map, ADDRESS_SPACE_PROGRAM, 8 )
	AM_RANGE(0x0000, 0x07ff) AM_READWRITE(bankedram_r, bankedram_w) AM_BASE(&ram)
	AM_RANGE(0x0800, 0x1fff) AM_RAM
	AM_RANGE(0x2000, 0x3fff) AM_ROMBANK(1)					 banked ROM 
	AM_RANGE(0x5f8c, 0x5f8c) AM_READ_PORT("P1")
	AM_RANGE(0x5f8d, 0x5f8d) AM_READ_PORT("P2")
	AM_RANGE(0x5f8e, 0x5f8e) AM_READ_PORT("DSW3")
	AM_RANGE(0x5f8f, 0x5f8f) AM_READ_PORT("DSW1")
	AM_RANGE(0x5f90, 0x5f90) AM_READ_PORT("DSW2")
	AM_RANGE(0x5fa0, 0x5faf) AM_READWRITE(K053244_r, K053244_w)
	AM_RANGE(0x5fb0, 0x5fbf) AM_WRITE(K053251_w)
	AM_RANGE(0x5fc0, 0x5fc0) AM_READWRITE(watchdog_reset_r, surpratk_5fc0_w)
	AM_RANGE(0x5fd0, 0x5fd1) AM_DEVWRITE("ym", ym2151_w)
	AM_RANGE(0x5fc4, 0x5fc4) AM_WRITE(surpratk_videobank_w)
	AM_RANGE(0x4000, 0x7fff) AM_READWRITE(K052109_r, K052109_w)
	AM_RANGE(0x8000, 0xffff) AM_ROM					 ROM
	ADDRESS_MAP_END
*/

UINT8 CSADriver::Read8(UINT64 offset) {
	// ports
	switch( offset ) {
		case 0x5fd0:	// YM2151
		case 0x5fd1:
			return ym->Read(offset & 1);
			
		default:
			break;
	}

	return memspace[offset & 0xffff];

}

void CSADriver::Write8(UINT64 offset, UINT8 data) {

	// ports
	switch( offset ) {
		case 0x5fd0:	// YM2151
		case 0x5fd1:
			ym->Write(offset & 1, data);
			break;
		case 0x5fc4:	// Video bankswitch (might be needed?)
			Msg("WARNING: Write to video bankswitch\n");
		default:		
			break;
	}

	// Prevent writes into ROM
	if (0x2000 <= offset || offset <= 0x3fff) return; // bankswitched ROM
	if (0x8000 <= offset || offset <= 0xffff) return; // main code

	memspace[offset & 0xffff] = data;
}

void CSADriver::KonamiSetlines(int lines) {
	
	// Get the bank ID and spew some debug info
	int target_bank = lines & 0x1f;
	UINT32 rom_offset = 0x10000 + (target_bank*0x2000);
	Msg("KONAMI: setlines %08X (bank %d, ROM offset %p)\n",lines, target_bank,rom_offset);
 
	// Copy the new bank into the memory space.
	memcpy(memspace + 0x2000, rom->GetRawMemory() + rom_offset, 0x2000);
}

void CSADriver::SndInterrupt(CBaseSoundDevice* dev, int status) {
	konami->Interrupt(KONAMI_FIRQ_LINE, status);
}

int CSADriver::Init(CHardware* hardware) {
	konami = new CKonamiCPU;

	konami->Init(CLOCK_MHZ(3));		// 3 MHz clock
	konami->SetCallbacks(this); // Setup CPU setlines callback
	konami->AssignMMU(MMU_PROGRAM_SPACE, this);

	ym = SoundDeviceFactory("YM2151");
	ym->Init(hardware->mixer, 3579545);
	ym->SetCallbacks(this);

	// Send off the CPU etc.
	hardware->AddCpu(konami);


	return 0;
}